<!--
 * @Author: liaoyu1992 1519778181@qq.com
 * @Date: 2022-11-04 19:29:54
 * @LastEditors: liaoyu1992 1519778181@qq.com
 * @LastEditTime: 2022-11-11 22:04:34
 * @FilePath: \kgantt\core\components\taskitem\TaskItem.vue
 * @Description: 
-->
<template>
  <g
    @keydown="onKeyDown"
    @mouseenter="onMouseEnter"
    @mouseleave="onMouseLeave"
    @dblclick="onDoubleClick"
    @click="onClick"
    @focus="onFocus"
  >
    <Milestone
      v-if="task.typeInternal === 'milestone'"
      :task="task"
      :is-progress-changeable="isProgressChangeable"
      :is-date-changeable="isDateChangeable"
      :is-selected="isSelected"
      :rtl="rtl"
      @on-event-start="onEventStart"
    ></Milestone>
    <Project
      v-else-if="task.typeInternal === 'project'"
      :task="task"
      :is-progress-changeable="isProgressChangeable"
      :is-date-changeable="isDateChangeable"
      :is-selected="isSelected"
      :rtl="rtl"
      @on-event-start="onEventStart"
    ></Project>
    <BarSmall
      v-else-if="task.typeInternal === 'smalltask'"
      :task="task"
      :is-progress-changeable="isProgressChangeable"
      :is-date-changeable="isDateChangeable"
      :is-selected="isSelected"
      :rtl="rtl"
      @on-event-start="onEventStart"
    ></BarSmall>
    <Bar
      v-else
      :task="task"
      :is-progress-changeable="isProgressChangeable"
      :is-date-changeable="isDateChangeable"
      :is-selected="isSelected"
      :rtl="rtl"
      @on-event-start="onEventStart"
    ></Bar>
    <text
      :x="getX()"
      :y="task.y + taskHeight * 0.5"
      :class="isTextInside ? 'kgantt-barLabel' : 'kgantt-barLabel kgantt-barLabelOutside'"
      ref="textRef"
    >
      {{ task.name }}
    </text>
  </g>
</template>
<script lang="ts" setup>
import { onMounted, PropType, ref, nextTick } from "vue";
import { BarTask } from "../../types/barTask";
import { GanttContentMoveAction } from "../../types/ganttTaskActions";
import Bar from "./bar/Bar.vue";
import BarSmall from "./bar/BarSmall.vue";
import Project from "./project/Project.vue";
import Milestone from "./milestone/Milestone.vue";
const props = defineProps({
  task: {
    type: Object as PropType<BarTask>,
    default: {},
  },
  arrowIndent: {
    type: Number,
    default: 0,
  },
  taskHeight: {
    type: Number,
    default: 0,
  },
  isProgressChangeable: {
    type: Boolean,
    default: false,
  },
  isDateChangeable: {
    type: Boolean,
    default: false,
  },
  isDelete: {
    type: Boolean,
    default: false,
  },
  isSelected: {
    type: Boolean,
    default: false,
  },
  rtl: {
    type: Boolean,
    default: false,
  },
});
let timer = ref();
const emits = defineEmits(["onEventStart"]);
const textRef = ref<SVGTextElement>();
const isTextInside = ref(true);
const onKeyDown = (event: KeyboardEvent) => {
  switch (event.key) {
    case "Delete": {
      if (props.isDelete) emits("onEventStart", "delete", props.task, event);
      break;
    }
  }
  event.stopPropagation();
};
const onEventStart = (
  action: GanttContentMoveAction,
  selectedTask: BarTask,
  event?: MouseEvent | KeyboardEvent
) => {
  emits("onEventStart", action, selectedTask, event);
};
const onMouseEnter = (event: MouseEvent | KeyboardEvent) => {
  emits("onEventStart", "mouseenter", props.task, event);
};
const onMouseLeave = (event: MouseEvent | KeyboardEvent) => {
  emits("onEventStart", "mouseleave", props.task, event);
};
const onDoubleClick = (event: MouseEvent | KeyboardEvent) => {
  if (timer.value) {
    clearTimeout(timer.value);
  }
  emits("onEventStart", "dblclick", props.task, event);
};
const onClick = (event: MouseEvent | KeyboardEvent) => {
  if (timer.value) {
    clearTimeout(timer.value);
  }
  timer.value = setTimeout(() => {
    emits("onEventStart", "click", props.task, event);
  }, 300);
};
const getX = () => {
  const width = props.task.x2 - props.task.x1;
  const hasChild = props.task.barChildren.length > 0;
  if (isTextInside) {
    return props.task.x1 + width * 0.5;
  }
  if (props.rtl && textRef.value) {
    return (
      props.task.x1 -
      textRef.value.getBBox().width -
      props.arrowIndent * +hasChild -
      props.arrowIndent * 0.2
    );
  } else {
    return (
      props.task.x1 +
      width +
      props.arrowIndent * +hasChild +
      props.arrowIndent * 0.2
    );
  }
};
const onFocus = () => {
  emits("onEventStart", "select", props.task);
};
onMounted(() => {
  nextTick(() => {
    if (textRef.value) {
      isTextInside.value =
        textRef.value.getBBox().width < props.task.x2 - props.task.x1;
    }
  });
});
</script>